package org.linlinjava.litemall.web.service;

import lombok.RequiredArgsConstructor;
import org.linlinjava.litemall.core.util.ResponseUtil;
import org.linlinjava.litemall.core.util.ResponseUtil.Response;
import org.linlinjava.litemall.db.domain.LitemallOrder;
import org.linlinjava.litemall.db.service.LitemallOrderService;
import org.linlinjava.litemall.web.vo.TodayDataVO;
import org.linlinjava.litemall.web.vo.TodayVO;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.time.LocalTime;
import java.util.*;
import static org.linlinjava.litemall.db.beans.Constants.*;

@Service
@RequiredArgsConstructor
public class WebTodayDataService {

    private final LitemallOrderService orderService;

    public Response<TodayVO> queryTodayData(boolean today, Integer userId,Integer shopId){
        //查询今日订单数据
        List<Short> orderStatus  = new ArrayList<>(Arrays.asList(new Short[]{ORDER_STATUS_HANG,ORDER_STATUS_NEW,ORDER_STATUS_ONGOING,ORDER_STATUS_PICKUP,ORDER_STATUS_FINISHED,STATUS_REFUND,STATUS_REFUND_CONFIRM}));
        List<LitemallOrder> todayOrders = orderService.queryTodayNotInOrderStatus(userId,today,orderStatus,null,null,"add_time","asc",shopId);

        //根据不同时间段划分数据
        Map<Integer,List<LitemallOrder>> ordersMap = new TreeMap<>();
        todayOrders.stream().forEach( order -> {
           Integer hour =  order.getAddTime().toLocalTime().getHour();

           //同一时间端的订单分组
            List<LitemallOrder> orders = ordersMap.get(hour);

            if(orders == null){
                orders = new ArrayList<>();
                orders.add(order);
                ordersMap.put(hour,orders);
            }else{
                orders.add(order);
            }
        });

        List<TodayDataVO> vos = new ArrayList<>();
        //根据map获取不同时段的分组订单
        ordersMap.keySet().stream().forEach(hour -> {
            TodayDataVO vo = new TodayDataVO();

            //每个时段的订单数据
            List<LitemallOrder> orders = ordersMap.get(hour);
            vo.setWholePoint(LocalTime.of(hour,0,0).toString());
            vo.setNumber(orders.size());

            //订单金额
            BigDecimal money = orders.stream().map(order -> order.getActualPrice()).reduce(BigDecimal.ZERO, BigDecimal::add);
            vo.setMoney(money);

            //销售额
            BigDecimal sale = orders.stream().filter(order->ORDER_STATUS_FINISHED.equals(order.getOrderStatus())).map(order -> order.getActualPrice()).reduce(BigDecimal.ZERO, BigDecimal::add);
            vo.setSale(sale);

            //退款金额
            BigDecimal refund = orders.stream().filter(order->STATUS_REFUND.equals(order.getOrderStatus())||STATUS_REFUND_CONFIRM.equals(order.getOrderStatus())).map(order -> order.getActualPrice()).reduce(BigDecimal.ZERO, BigDecimal::add);
            vo.setRefund(refund);
            vos.add(vo);
        });

        Integer totalNum = todayOrders.size();
        BigDecimal totalMoney = todayOrders.stream().map(order -> order.getActualPrice()).reduce(BigDecimal.ZERO, BigDecimal::add);
        BigDecimal totalSale = todayOrders.stream().filter(order->ORDER_STATUS_FINISHED.equals(order.getOrderStatus())).map(order -> order.getActualPrice()).reduce(BigDecimal.ZERO, BigDecimal::add);
        TodayVO vo = new TodayVO();
        vo.setTotalNum(totalNum);
        vo.setTotalMoney(totalMoney);
        vo.setTotalSale(totalSale);
        BigDecimal totalRefund = todayOrders.stream().filter(order->STATUS_REFUND.equals(order.getOrderStatus())||STATUS_REFUND_CONFIRM.equals(order.getOrderStatus())).map(order -> order.getActualPrice()).reduce(BigDecimal.ZERO, BigDecimal::add);
        vo.setTotalRefund(totalRefund);
        vo.setVos(vos);
        return ResponseUtil.ok(vo);
    }
}
